package Main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.Random;

import particulas.Objeto;
import particulas.Particula;
import Screens.Screen;
import Screens.TelaCreditos;
import Screens.TelaGameOver;
import Screens.TelaInicial;
import Screens.TelaJogo;
import Screens.TelaTreinamento;
import Screens.TelaWin;
import Utils.Constantes;

@SuppressWarnings("serial")
public class GamePanel extends Canvas implements Runnable {
	//============== VERSAO ==============
	//	private final static double versao = 0.01;
	//=============== O Tamanho da tela =================
	public static final int PWIDTH = 900; 
	public static final int PHEIGHT = 500;
	//===================================================
	private Thread animator; // for the animation
	private boolean running = false; // stops the animation
	@SuppressWarnings("unused")
	private boolean gameOver = false; // for game termination
	public static GamePanel instance = null;
	float FPS,SFPS;
	int fpscount;
	public Random rnd = new Random();
	
	//Telas 
	public static final int TELA_INICIAL = 0;
	public static final int TELA_TREINAMENTO = 1;
	public static final int TELA_JOGO = 2;
	public final int TELA_GAME_WIN = 3;
	public static final int TELA_CREDITOS = 4;
	public static final int TELA_GAME_OVER = 5;
	
	public static ArrayList <Particula> listaParticulas;
	public final int numeroTelas =6;
	public static Screen []telas;
	public static int TELA_ATIVA;
	public static int money;
	public final static int moneyInicial = 200;
	public static boolean reiniciaFasesTreino;
	public static boolean reiniciaJogo;
	public static boolean shakeScreen = false;
	public int timerShake = 0;
	
	public GamePanel() {
		instance = this;
		setBackground(Color.white);
		setPreferredSize( new Dimension(PWIDTH, PHEIGHT));
		money = moneyInicial;
		// create game components
		setFocusable(true);
		requestFocus(); // JPanel now receives key events
		
		inicializaAtributos();
		telas = new Screen[numeroTelas];
		TELA_ATIVA = TELA_INICIAL;
		telas[TELA_INICIAL]= new TelaInicial(0, 0, PWIDTH, PHEIGHT, "/telas/tela_inicial.png");
		inicializaTreinamento();
		inicializaJogo();		
		telas[TELA_GAME_OVER] = new TelaGameOver(0, 0, PWIDTH, PHEIGHT, "/telas/tela_game_over.png");
		telas[TELA_CREDITOS] = new TelaCreditos(0, 0, PWIDTH, PHEIGHT, "/telas/tela_creditos.png");
		telas[TELA_GAME_WIN] = new TelaWin(0, 0, PWIDTH, PHEIGHT, "/telas/tela_game_win.png");
		
		listaParticulas = new ArrayList<Particula>();
		
		
		// Adiciona um Key Listner
		addKeyListener( new KeyAdapter() {
			public void keyPressed(KeyEvent e)
			{ 
				telas[TELA_ATIVA].tratadorTecladoPress(e);

			}
			@Override
			public void keyReleased(KeyEvent e ) {
								
			}
		});

		addMouseMotionListener(new MouseMotionListener() {

			@Override
			public void mouseMoved(MouseEvent e) {
				telas[TELA_ATIVA].mouseMoved(e);
			}

			@Override
			public void mouseDragged(MouseEvent e) {
				
				telas[TELA_ATIVA].mouseDragged(e);
				
			}
		});

		addMouseListener(new MouseListener() {

			@Override
			public void mouseReleased(MouseEvent e) {
//				telas[TELA_ATIVA].mouseReleased(e);
			}

			@Override
			public void mousePressed(MouseEvent e) {
//				telas[TELA_ATIVA].mousePressed(e);
			

			}

			@Override
			public void mouseExited(MouseEvent e) {
				

			}

			@Override
			public void mouseEntered(MouseEvent e) {
				

			}

			@Override
			public void mouseClicked(MouseEvent e) {
				telas[TELA_ATIVA].mouseClicked(e);
				

				
			}
		});
		// TUDO VAI SER INICIALIZADO APARTIR DAQUI 


	} // end of GamePanel()

	
	public void inicializaTreinamento(){
		money = 200;
		reiniciaFasesTreino = false;
		inicializaAtributos();
		telas[TELA_TREINAMENTO]= new TelaTreinamento(0, 0, PWIDTH, PHEIGHT, "/telas/tela_beltame.png");	
		
		
	}
	
	public void inicializaJogo(){
		money = 200;
		reiniciaJogo = false;
		inicializaAtributos();
		telas[TELA_JOGO]= new TelaJogo(0, 0, PWIDTH, PHEIGHT, "/telas/tela_inicial.png");
	}
	
	public void inicializaAtributos(){
		Constantes.carregaMapas("csv/mapas.csv");
		Constantes.carregaSons("csv/sons.csv");
		Constantes.carregaImagemInimigos("csv/imagensInimigos.csv");
		for(int i=0; i<Constantes.listaMapas.size(); i++){
			Constantes.listaMapas.get(i).waveAtual =0;
		}
		Constantes.listaMapas.get(Constantes.mapaAtual).carregaWave(Constantes.listaMapas.get(Constantes.mapaAtual).waveAtual);		
		Constantes.carregaImagemManchas();
	}
	
	public static void setReinicioTreinamento(){
		reiniciaFasesTreino = true;
	}

	/***********************
	 * N�O MEXER 
	 */
	public void startGame()
	// initialise and start the thread
	{
		if (animator == null || !running) {
			animator = new Thread(this);
			animator.start();
		}
	} // end of startGame()

	public void stopGame()
	// called by the user to stop execution
	{ running = false; }


	public void run()
	/* Repeatedly update, render, sleep */
	{
		running = true;

		long DifTime,TempoAnterior;

		int segundo = 0;
		DifTime = 0;
		TempoAnterior = System.currentTimeMillis();

		this.createBufferStrategy(2);
		BufferStrategy strategy = this.getBufferStrategy();

		while(running) {

			gameUpdate(DifTime); // game state is updated
			Graphics g = strategy.getDrawGraphics();
			gameRender((Graphics2D)g); // render to a buffer
			strategy.show();

			try {
				Thread.sleep(5); // sleep a bit
			}	
			catch(InterruptedException ex){}

			DifTime = System.currentTimeMillis() - TempoAnterior;
			TempoAnterior = System.currentTimeMillis();

			if(segundo!=((int)(TempoAnterior/1000))){
				FPS = SFPS;
				SFPS = 1;
				segundo = ((int)(TempoAnterior/1000));
			}else{
				SFPS++;
			}

		}
		Constantes.soundplayer.Stop();
		System.exit(0); // so enclosing JFrame/JApplet exits
	} // end of run()


	private void gameUpdate(long diffTime)
	{ 
		if (shakeScreen){
			timerShake += diffTime;
			if (timerShake>=250){
				timerShake = 0; 
				shakeScreen = false;
			}
		}
//		System.out.println(diffTime);
		if(reiniciaFasesTreino){
			//System.out.println("reinicia fase ");
			inicializaTreinamento();
			
		}
		if(reiniciaJogo){
			inicializaJogo();
		}
		telas[TELA_ATIVA].Update(diffTime);		
		for (int i = 0; i < listaParticulas.size(); i++) {
			((Objeto) listaParticulas.get(i)).simulaSe(diffTime);
			if (listaParticulas.get(i).vivo == false) {
				listaParticulas.remove(i);
			}
		}
	}
	
	
	
	
	
	

	private void gameRender(Graphics2D dbg)
	// draw the current frame to an image buffer
	{
		//TODO
		// clear the background
		dbg.setColor(Color.white);
		dbg.fillRect (0, 0, PWIDTH+10, PHEIGHT+10);
		int offsetx = 0;
		int offsety = 0;
		if (shakeScreen){
			offsetx = -5+rnd.nextInt(10);
			offsety = -5+rnd.nextInt(10);
		}
		dbg.translate(offsetx, offsety);
		// ==== Tudo vai apartir daqui 
		telas[TELA_ATIVA].Draw(dbg);
		for (int i = 0; i < listaParticulas.size(); i++) {
			listaParticulas.get(i).desenhaSe(dbg, 0, 0);
		}
		dbg.setColor(Color.BLACK);
		dbg.drawString("FPS: "+FPS , 10, 10);
		dbg.translate(-offsetx, -offsety);

	}

}

